static void Main(string[] args)
{
OpenLock();
}
private static void OpenLock()
{
string[] deadends = new string[] { "1234", "5678" };
int count = OpenLock(deadends, "1235");
Console.WriteLine($"最小步數: {count}");
Console.ReadKey();
}
/// <summary>
/// 打開密碼鎖
/// </summary>
/// <param name="deadends">死亡密碼</param>
/// <param name="target">目標密碼</param>
/// <returns></returns>
public static int OpenLock(string[] deadends, string target)
{
//使用 HashSet 避免有重覆死亡密碼
var dead = new HashSet<string>(deadends);
var visited = new HashSet<string>();//訪問過清單
var queue = new Queue<string>();
//添加元素
queue.Enqueue("0000");
visited.Add("0000");
int steps = 0;
while (queue.Count > 0)
{
int size = queue.Count;
for (int i = 0; i < size; i++)
{
var current = queue.Dequeue();
if (dead.Contains(current)) continue;
if (current == target) return steps;
foreach (var next in GetNext(current))
{
Console.WriteLine($"經過順序: {next}");
/* 初始化: 0000 開始轉會如下
經過順序: 1000
經過順序: 9000
經過順序: 0100
經過順序: 0900
經過順序: 0010
經過順序: 0090
經過順序: 0001
經過順序: 0009
*/
if (!visited.Contains(next))
{
queue.Enqueue(next);
visited.Add(next);
}
}
}
steps++;
}
return -1; // 如果無法達到目標
}
/// <summary>
/// 轉盤 每次 +1 -1
/// </summary>
/// <param name="combination"></param>
/// <returns></returns>
private static IEnumerable<string> GetNext(string combination)
{
char[] chars = combination.ToCharArray();
for (int i = 0; i < 4; i++)
{
char c = chars[i];
chars[i] = c == '9' ? '0' : (char)(c + 1);
yield return new System.String(chars);
chars[i] = c == '0' ? '9' : (char)(c - 1);
yield return new System.String(chars);
chars[i] = c;
}
}
Leetcode 752. Open the Lock
用 graph
去解,然後使用 BFS
去搜尋最短路徑
Time complexity: O(n)